using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
using Book.Blog.Core.DTOs;
using Book.Blog.Core.Entities;
using Book.Blog.Core.Interfaces;
using System.Linq;

namespace Book.Blog.API.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class CommentsController : ControllerBase
    {
        private readonly IRepository<Comment> _commentRepository;
        private readonly IRepository<Post> _postRepository;
        private readonly IUnitOfWork _unitOfWork;
        private readonly UserManager<User> _userManager;

        public CommentsController(
            IRepository<Comment> commentRepository,
            IRepository<Post> postRepository,
            IUnitOfWork unitOfWork,
            UserManager<User> userManager)
        {
            _commentRepository = commentRepository;
            _postRepository = postRepository;
            _unitOfWork = unitOfWork;
            _userManager = userManager;
        }

        /// <summary>
        /// 获取评论列表（支持分页、按文章、按用户、按审核状态过滤）
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">每页数量</param>
        /// <param name="postId">文章ID</param>
        /// <param name="userId">用户ID</param>
        /// <param name="isApproved">是否已审核</param>
        /// <returns>评论分页列表</returns>
        [HttpGet]
        public async Task<ActionResult<CommentPagedListDTO>> GetComments(
            [FromQuery] int pageIndex = 1,
            [FromQuery] int pageSize = 10,
            [FromQuery] Guid? postId = null,
            [FromQuery] Guid? userId = null,
            [FromQuery] bool? isApproved = null)
        {
            var query = _unitOfWork.Comments.GetAllAsync().Result.AsQueryable();

            if (postId.HasValue)
            {
                query = query.Where(c => c.PostId == postId.Value);
            }

            if (userId.HasValue)
            {
                query = query.Where(c => c.AuthorId == userId.Value);
            }

            if (isApproved.HasValue)
            {
                query = query.Where(c => c.IsApproved == isApproved.Value);
            }

            var totalCount = query.Count();
            var items = await query
                .OrderByDescending(c => c.CreatedTime)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .Select(c => new CommentListDTO
                {
                    Id = c.Id,
                    Content = c.Content,
                    LikeCount = c.LikeCount,
                    IsApproved = c.IsApproved,
                    CreatedTime = c.CreatedTime,
                    PostId = c.PostId,
                    PostTitle = c.Post.Title,
                    UserId = c.AuthorId,
                    UserName = c.Author.UserName,
                    UserAvatar = c.Author.Avatar,
                    ReplyCount = c.Replies.Count
                })
                .ToListAsync();

            return new CommentPagedListDTO
            {
                Items = items,
                TotalCount = totalCount,
                PageIndex = pageIndex,
                PageSize = pageSize,
                TotalPages = (int)Math.Ceiling(totalCount / (double)pageSize),
                HasPreviousPage = pageIndex > 1,
                HasNextPage = pageIndex < (int)Math.Ceiling(totalCount / (double)pageSize)
            };
        }

        /// <summary>
        /// 获取评论详情
        /// </summary>
        /// <param name="id">评论ID</param>
        /// <returns>评论详情</returns>
        [HttpGet("{id}")]
        public async Task<ActionResult<CommentDTO>> GetComment(Guid id)
        {
            var comment = await _unitOfWork.Comments.GetByIdAsync(id);
            if (comment == null)
            {
                return NotFound();
            }

            return await BuildCommentDTO(comment);
        }

        /// <summary>
        /// 添加评论（需登录）
        /// </summary>
        /// <param name="model">评论信息</param>
        /// <returns>新建评论详情</returns>
        /// <remarks>
        /// 示例请求:
        /// {
        ///   "postId": "文章ID",
        ///   "content": "评论内容",
        ///   "parentId": "父评论ID（可选）"
        /// }
        /// </remarks>
        [HttpPost]
        [Authorize]
        public async Task<ActionResult<CommentDTO>> CreateComment(CreateCommentDTO model)
        {
            var user = await _userManager.GetUserAsync(User);
            var post = await _unitOfWork.Posts.GetByIdAsync(model.PostId);
            if (post == null)
            {
                return NotFound("文章不存在");
            }

            Comment? parent = null;
            if (model.ParentId.HasValue)
            {
                parent = await _unitOfWork.Comments.GetByIdAsync(model.ParentId.Value);
                if (parent == null)
                {
                    return NotFound("父评论不存在");
                }
            }

            var comment = new Comment
            {
                Content = model.Content,
                Post = post,
                Author = user,
                Parent = parent,
                IsApproved = await _userManager.IsInRoleAsync(user, "Admin") // 管理员评论自动通过
            };

            await _unitOfWork.Comments.AddAsync(comment);
            
            // 更新文章评论计数
            post.CommentCount = post.Comments.Count + 1;
            
            await _unitOfWork.SaveChangesAsync();

            return await BuildCommentDTO(comment);
        }

        /// <summary>
        /// 更新评论（需作者或管理员）
        /// </summary>
        /// <param name="id">评论ID</param>
        /// <param name="model">评论信息</param>
        /// <returns>无内容</returns>
        [HttpPut("{id}")]
        [Authorize]
        public async Task<IActionResult> UpdateComment(Guid id, UpdateCommentDTO model)
        {
            var comment = await _unitOfWork.Comments.GetByIdAsync(id);
            if (comment == null)
            {
                return NotFound();
            }

            var user = await _userManager.GetUserAsync(User);
            if (comment.AuthorId != user.Id && !await _userManager.IsInRoleAsync(user, "Admin"))
            {
                return Forbid();
            }

            comment.Content = model.Content;
            comment.UpdatedAt = DateTime.UtcNow;
            
            await _unitOfWork.SaveChangesAsync();

            return NoContent();
        }

        /// <summary>
        /// 删除评论（需作者或管理员）
        /// </summary>
        /// <param name="id">评论ID</param>
        /// <returns>无内容</returns>
        [HttpDelete("{id}")]
        [Authorize]
        public async Task<IActionResult> DeleteComment(Guid id)
        {
            var comment = await _unitOfWork.Comments.GetByIdAsync(id);
            if (comment == null)
            {
                return NotFound();
            }

            var user = await _userManager.GetUserAsync(User);
            if (comment.AuthorId != user.Id && !await _userManager.IsInRoleAsync(user, "Admin"))
            {
                return Forbid();
            }

            // 更新文章评论计数
            var post = comment.Post;
            post.CommentCount = post.Comments.Count - 1;

            // 删除所有回复
            foreach (var reply in comment.Replies.ToList())
            {
                await _unitOfWork.Comments.DeleteAsync(reply);
            }

            await _unitOfWork.Comments.DeleteAsync(comment);
            await _unitOfWork.SaveChangesAsync();

            return NoContent();
        }

        /// <summary>
        /// 审核通过评论（需管理员）
        /// </summary>
        /// <param name="id">评论ID</param>
        /// <returns>无内容</returns>
        [HttpPost("{id}/approve")]
        [Authorize(Roles = "Admin")]
        public async Task<IActionResult> ApproveComment(Guid id)
        {
            var comment = await _unitOfWork.Comments.GetByIdAsync(id);
            if (comment == null)
            {
                return NotFound();
            }

            comment.IsApproved = true;
            comment.UpdatedAt = DateTime.UtcNow;
            
            await _unitOfWork.SaveChangesAsync();

            return NoContent();
        }

        /// <summary>
        /// 驳回评论（需管理员）
        /// </summary>
        /// <param name="id">评论ID</param>
        /// <returns>无内容</returns>
        [HttpPost("{id}/reject")]
        [Authorize(Roles = "Admin")]
        public async Task<IActionResult> RejectComment(Guid id)
        {
            var comment = await _unitOfWork.Comments.GetByIdAsync(id);
            if (comment == null)
            {
                return NotFound();
            }

            comment.IsApproved = false;
            comment.UpdatedAt = DateTime.UtcNow;
            
            await _unitOfWork.SaveChangesAsync();

            return NoContent();
        }

        /// <summary>
        /// 点赞评论（需登录）
        /// </summary>
        /// <param name="id">评论ID</param>
        /// <returns>无内容</returns>
        [HttpPost("{id}/like")]
        [Authorize]
        public async Task<IActionResult> LikeComment(Guid id)
        {
            var comment = await _unitOfWork.Comments.GetByIdAsync(id);
            if (comment == null)
            {
                return NotFound();
            }

            comment.LikeCount++;
            await _unitOfWork.SaveChangesAsync();

            return NoContent();
        }

        private async Task<CommentDTO> BuildCommentDTO(Comment comment)
        {
            var replies = new List<CommentDTO>();
            foreach (var reply in comment.Replies)
            {
                replies.Add(await BuildCommentDTO(reply));
            }

            return new CommentDTO
            {
                Id = comment.Id,
                Content = comment.Content,
                LikeCount = comment.LikeCount,
                IsApproved = comment.IsApproved,
                CreatedTime = comment.CreatedTime,
                UpdatedTime = comment.UpdatedTime,
                PostId = comment.PostId,
                PostTitle = comment.Post.Title,
                UserId = comment.AuthorId,
                UserName = comment.Author.UserName,
                UserAvatar = comment.Author.Avatar,
                ParentId = comment.ParentId,
                Parent = comment.Parent != null ? await BuildCommentDTO(comment.Parent) : null,
                Replies = replies
            };
        }
    }
} 